﻿#region Namespaces

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

#endregion

namespace Vibstudio.X4NET.Collections
{
    public static class EnumerableExtensions
    {
        public static bool CompareList<T>(this IList<T> list1, IList<T> list2)
        {
            // If any of the list is null, return false
            if ((list1 == null && list2 != null) || (list2 == null && list1 != null))
            {
                return false;
            }

            // If both lists are null, return true, since its same
            if (list1 == null)
            {
                return true;
            }

            // If count don't match between 2 lists, then return false
            if (list1.Count != list2.Count)
            {
                return false;
            }

            bool isEqual = true;
            foreach (T item in list1)
            {
                T object1 = item;
                T object2 = list2.ElementAt(list1.IndexOf(item));
                Type type = typeof(T);
            
                // If any of the object inside list is null and other list has some value for the same object  then return false
                if ((object1 == null && object2 != null) || (object2 == null && object1 != null))
                {
                    isEqual = false;
                    break;
                }

                foreach (PropertyInfo property in type.GetProperties())
                {
                    if (property.Name != "ExtensionData")
                    {
                        string object1Value = string.Empty;
                        string object2Value = string.Empty;

                        try
                        {
                            if (type.GetProperty(property.Name).GetValue(object1, null) != null)
                            {
                                object1Value = type.GetProperty(property.Name).GetValue(object1, null).ToString();
                            }
                        }
                        catch (TargetParameterCountException)
                        {
                            continue;
                        }

                        try
                        {
                            if (type.GetProperty(property.Name).GetValue(object2, null) != null)
                            {
                                object2Value = type.GetProperty(property.Name).GetValue(object2, null).ToString();
                            }
                        }
                        catch (TargetParameterCountException)
                        {
                            continue;
                        }

                        // If any of the property value inside an object in the list didnt match, return false
                        if (object1Value.Trim() != object2Value.Trim())
                        {
                            isEqual = false;
                            break;
                        }
                    }
                }
            }
            
            // If all the properties are same then return true
            return isEqual;
        }
    }
}